// 处理手柄的事件
// 在这个函数对所有手柄的事件进行处理
// 通过channel.rs的线程通信通道发送手柄状态
// 这个函数是个死循环, 在axum在新开的线程初始化后, 主线程将会在这里等待手柄事件(阻塞)
use super::channel;
use std::collections::HashMap;
use sdl2::controller::{Axis, Button, GameController};
use sdl2::event::Event;
use crate::runtime::GLOBAL_RUNTIME;
use once_cell::sync::Lazy;
use std::time::{Instant};
use tokio::time::sleep;
use tokio::time::Duration;
use crate::web_rtc::close::close;
use crate::api::get_session_id::get_session_id_status;
use std::sync::Arc;
use tokio::sync::Mutex;
use crate::web_rtc::off_line_time::get_off_line_time;
use super::reverse::{get_x_reverse, get_y_reverse};

// 必须持有手柄对象才可以获取事件
static mut CONTROLLER_MAP: Lazy<HashMap<u32, GameController>> = Lazy::new(|| HashMap::new());
pub fn handle_controller_event() {
    // 获取手柄x轴和y轴是否反向
    let (x_reverse, y_reverse) = GLOBAL_RUNTIME.block_on(
        async {
            (get_x_reverse().await, get_y_reverse().await)
        }
    );

    // 自动离线时间
    let offline_time = GLOBAL_RUNTIME.block_on(
        async {
            get_off_line_time().await
        }
    );
    // 更换成秒
    let offline_time = offline_time*60;

    let sdl_context = sdl2::init().unwrap();
    // 在windows的环境下, 需要新开窗口, 窗口聚焦在前才能检测到手柄
    // 在linux下不需要
    // let video_subsystem = sdl_context.video().unwrap();
    // let _window = video_subsystem
    //     .window("手柄测试", 640, 480)
    //     .position_centered()
    //     .vulkan()
    //     .build()
    //     .unwrap();


    let controller_subsystem = sdl_context.game_controller().unwrap();
    // 事件队列
    let mut event_pump = sdl_context.event_pump().unwrap();
    // 必须持有手柄对象才可以获取事件

    // 初始化共享时间戳
    let last_event_time = Arc::new(Mutex::new(Instant::now()));

    // 异步任务中使用
    let time_for_async = last_event_time.clone();
    GLOBAL_RUNTIME.spawn(async move {
        loop {
            sleep(Duration::from_secs(1)).await;
            if get_session_id_status() {
                let time = time_for_async.lock().await;
                if time.elapsed() > Duration::from_secs(offline_time) {
                    println!("手柄长时间({}分钟)无事件, 结束串流", offline_time/60);
                    close().await;
                }
            } else {
                let mut time = time_for_async.lock().await;
                *time = Instant::now();
            }
        }
    });
    loop {
        for event in event_pump.poll_iter() {
            // 异步更新时间戳，避免阻塞主线程
            let time_for_sync = last_event_time.clone();
            GLOBAL_RUNTIME.spawn(async move {
                let mut time = time_for_sync.lock().await;
                *time = Instant::now();
            });
            match event {
                // 手柄连接事件
                Event::ControllerDeviceAdded { timestamp, which } => {
                    let controller = controller_subsystem.open(which).expect("failed to open controller");
                    let id = controller.instance_id();
                    unsafe {
                        CONTROLLER_MAP.insert(id, controller);
                    }
                    let tx = channel::CONNECT_STATUS_CHANNEL.0.clone();
                    GLOBAL_RUNTIME.spawn(async move {
                        tx.send("controller connected".to_string()).await.unwrap();
                    });
                }
                // 手柄断开事件
                Event::ControllerDeviceRemoved { timestamp, which } => {
                    unsafe {
                        CONTROLLER_MAP.remove(&which);
                    }
                    let tx = channel::CONNECT_STATUS_CHANNEL.0.clone();
                    GLOBAL_RUNTIME.spawn(async move {
                        tx.send("controller disconnected".to_string()).await.unwrap();
                    });
                }
                // 手柄摇杆事件
                Event::ControllerAxisMotion { timestamp, which, axis, value } => {
                    let tx = channel::AXIS_CHANNEL.0.clone();
                    let mut message = String::new();
                    match axis {
                        Axis::LeftX => {
                            if x_reverse {
                                // x轴反向
                                message = format!("leftx = {}", value.saturating_neg());
                            } else {
                                message = format!("leftx = {}", value);
                            }
                        }
                        Axis::LeftY => {
                            if y_reverse {
                                // y轴反向
                                message = format!("lefty = {}", value.saturating_neg());
                            } else {
                                message = format!("lefty = {}", value);
                            } 
                        }
                        Axis::RightX => {
                            if x_reverse {
                                // x轴反向
                                message = format!("rightx = {}", value.saturating_neg());
                            } else {
                                message = format!("rightx = {}", value);
                            }
                        }
                        Axis::RightY => {
                            if y_reverse {
                                // y轴反向
                                message = format!("righty = {}", value.saturating_neg());
                            } else {
                                message = format!("righty = {}", value);
                            }
                        }
                        Axis::TriggerLeft => {
                            message = format!("triggerleft = {}", value);
                        }
                        Axis::TriggerRight => {
                            message = format!("triggerright = {}", value);
                        }
                    }
                    tx.send(message).unwrap_or_else(|_| eprintln!("failed to send ControllerAxisMotion"));
                }
                // 手柄按钮按下事件
                Event::ControllerButtonDown { timestamp, which, button } => {
                    let tx = channel::BUTTON_CHANNEL.0.clone();
                    let mut message = String::new();
                    match button {
                        Button::A => {
                            message = format!("A = Down");
                        }
                        Button::X => {
                            message = format!("X = Down");
                        }
                        Button::B => {
                            message = format!("B = Down");
                        }
                        Button::Y => {
                            message = format!("Y = Down");
                        }
                        // LB
                        Button::LeftShoulder => {
                            message = format!("LeftShoulder = Down");
                        }
                        // RB
                        Button::RightShoulder => {
                            message = format!("RightShoulder = Down");
                        }
                        // LS
                        Button::LeftStick => {
                            message = format!("LeftStick = Down");
                        }
                        // RS
                        Button::RightStick => {
                            message = format!("RightStick = Down");
                        }
                        // 左
                        Button::DPadLeft => {
                            message = format!("DPadLeft = Down");
                        }
                        // 右
                        Button::DPadRight => {
                            message = format!("DPadRight = Down");
                        }
                        // 上
                        Button::DPadUp => {
                            message = format!("DPadUp = Down");
                        }
                        // 下
                        Button::DPadDown => {
                            message = format!("DPadDown = Down");
                        }
                        // Xbox西瓜键
                        Button::Guide => {
                            message = format!("Guide = Down");
                        }
                        // Xbox 手柄的 View键, 中间偏左
                        Button::Back => {
                            message = format!("Back = Down");
                        }
                        // Xbox 手柄的 Menu键, 中间偏右
                        Button::Start => {
                            message = format!("Start = Down");
                        }
                        _ => {}
                    }
                    tx.send(message).unwrap_or_else(|_| eprintln!("failed to send ControllerButtonDown"));
                }
                Event::ControllerButtonUp { timestamp, which, button } => {
                    let tx = channel::BUTTON_CHANNEL.0.clone();
                    let mut message = String::new();
                    match button {
                        Button::A => {
                            message = format!("A = Up");
                        }
                        Button::X => {
                            message = format!("X = Up");
                        }
                        Button::B => {
                            message = format!("B = Up");
                        }
                        Button::Y => {
                            message = format!("Y = Up");
                        }
                        // LB
                        Button::LeftShoulder => {
                            message = format!("LeftShoulder = Up");
                        }
                        // RB
                        Button::RightShoulder => {
                            message = format!("RightShoulder = Up");
                        }
                        // LS
                        Button::LeftStick => {
                            message = format!("LeftStick = Up");
                        }
                        // RS
                        Button::RightStick => {
                            message = format!("RightStick = Up");
                        }
                        // 左
                        Button::DPadLeft => {
                            message = format!("DPadLeft = Up");
                        }
                        // 右
                        Button::DPadRight => {
                            message = format!("DPadRight = Up");
                        }
                        // 上
                        Button::DPadUp => {
                            message = format!("DPadUp = Up");
                        }
                        // 下
                        Button::DPadDown => {
                            message = format!("DPadDown = Up");
                        }
                        // Xbox西瓜键
                        Button::Guide => {
                            message = format!("Guide = Up");
                        }
                        // Xbox 手柄的 View键, 中间偏左
                        Button::Back => {
                            message = format!("Back = Up");
                        }
                        // Xbox 手柄的 Menu键, 中间偏右
                        Button::Start => {
                            message = format!("Start = Up");
                        }
                        _ => {}
                    }
                    tx.send(message).unwrap_or_else(|_| eprintln!("failed to send ControllerButtonUp"));
                }
                _ => {}
            }
        }
    }

}
// 机身震动
pub fn controller_rumble(low_frequency_rumble: u16, high_frequency_rumble: u16, duration_ms: u32) {
    for controller in unsafe {CONTROLLER_MAP.iter_mut()} {
        if(controller.1.has_rumble()) {
            controller.1.set_rumble(low_frequency_rumble, high_frequency_rumble, duration_ms).unwrap();
        }
    }
}
// 扳机震动
pub fn controller_rumble_trigger(left_rumble: u16, right_rumble: u16, duration_ms: u32) {
    for controller in unsafe {CONTROLLER_MAP.iter_mut()} {
        if(controller.1.has_rumble_triggers()) {
            controller.1.set_rumble_triggers(left_rumble, right_rumble, duration_ms).unwrap();
        }
    }
}